#!/usr/bin/env python3

def hamming_distance(string1, string2):
    if len(string1) != len(string2):
        raise ValueError("strings must be of equal length.")
    dist_counter = 0
    for n in range(len(string1)):
        if string1[n] != string2[n]:
            dist_counter += 1
    return dist_counter

def check_code(name, code):
    print(f'code {name} is {code}')
    combine = lambda x, y: ''.join([a if a == b else '0' for a, b in zip(x, y)])
    check_validity = lambda x, y, z: not (z in x or z in y)
    result = True
    for i, x in enumerate(code):
        for j, y in enumerate(code[i + 1:]):
            z = combine(x, y)
            valid = check_validity(x, y, z)
            result = result and valid
            hdxy = hamming_distance(x, y)
            hdzx = hamming_distance(z, x)
            hdzy = hamming_distance(z, y)
            if not valid:
                print(f'z={z} in x={x} or y={y}, not valid (hamming distance = {hamming_distance(x, y)})')
                print(f'hd_x_y = {hdxy}, hd_z_x = {hdzx}, hd_z_y = {hdzy}')
    print(f'code {name} is{"" if result else " not"} valid')
    print()

def main():
    codes = {
            'A': ['00011', '00110', '01010', '01101', '10010', '10101', '11001', '11100'],
            'B': ['10101', '01000', '00100', '00010'],
            'C': ['0010001', '0010010', '0010100', '0011000', '0001001', '0001010', '0000101', '0000110', '1000001', '1000010', '1000100', '1001000', '0100001', '0100010', '0100100', '0101000'],
            'D': ['001', '011', '101', '110'],
            'E': ['110001', '110010', '110100', '111000', '011010', '011100', '100011', '100101', '101001', '101010', '101100', '010011', '010101', '010110', '011001', '100110'],
            'F': ['00100', '10001', '01010', '11001', '00011', '11000'],
            'G': ['1110', '0111', '1011', '1101'],
            'H': ['0001', '0010', '0100', '1000'],
            'I': ['0000100', '0001011', '0010011', '0011010', '0100011', '0101010', '0110010', '0111001', '1000011', '1001010', '1010010', '1011001', '1100010', '1101001', '1110001', '1111000'],
            'J': ['1110000', '0011000', '0001110', '0000011', '1010100', '1000001', '0101010', '0000110'],
    }

    for key in codes:
        check_code(key, codes[key])

if __name__ == '__main__':
    main()
